﻿//////////////////////////////////////////////////////////////////////////////
//
//  Copyright © 1998-2024 Glodon Company Limited.  All rights reserved.
//
//  Use of this software is subject to the terms of the Glodon license
//  agreement provided at the time of installation or download, or which
//  otherwise accompanies this software in either electronic or hard copy form.  
//
//////////////////////////////////////////////////////////////////////////////


#pragma once
#include "GcmpModelInterface.h"
#include "IExternalObject.h"

namespace gcmp
{
    class IDrawingViewport;
    class IModelView;
    class IDrawingViewportEvent;
    class IPolygon;
    class Coordinate3d;

    /// \brief 图纸接口
    ///
    /// 查找、设置图纸名称；查找图纸对应的视图
    /// 管理图纸上的视口，能创建、删除和查找视口
    FINAL_INTERFACE class GCMP_MODEL_INTERFACE_EXPORT IDrawingLayout : public IExternalObject
    {
        DEFINE_CAST_DERIVED(gcmp::IDrawingLayout, gcmp::IExternalObject)
    public:
        /// \brief 析构函数
        virtual ~IDrawingLayout();
        
        /// \brief 设置图纸名称,图纸名称唯一
        /// 
        /// \param name 图纸名称
        /// \return 返回true表示设置成功，否则设置失败
        virtual bool SetName(const std::wstring& name) = 0;

        /// \brief 获取图纸名称
        ///
        /// \return 返回图纸名称
        virtual const std::wstring& GetName() const = 0;

        /// \brief 获取图纸对应的ModelView的Id
        ///
        /// \return 返回图纸对应的ModelView的Id
        virtual ElementId GetModelViewId() const = 0;

        /// \brief 获取图纸对应的ModelView的指针
        ///
        /// \return 返回图纸对应的ModelView的指针
        virtual IModelView* GetModelView() = 0;

        /// \brief 获取图纸对应的ModelView的指针
        ///
        /// \return 返回图纸对应的ModelView的指针
        virtual const IModelView* GetModelView() const = 0;

        /// \brief 创建一个视口
        /// 
        /// \param modelViewId 视口对应的ModelView的Id
        /// \param name 视口名称，视口名称唯一
        /// \param bottomLeftPoint 视口在图纸中的左下角的世界坐标
        /// \param errorMessage 输出错误信息，为可选参数。失败情况下获取错误信息
        /// \param isDifferent  外框内框是否一致，Gap产品为true, 别的产品不变为默认参数false
        /// \return 创建成功返回视口指针,失败返回nullptr
        virtual IDrawingViewport* CreateViewport(ElementId modelViewId, const std::wstring& name, Vector3d bottomLeftPoint, std::wstring* errorMessage = nullptr, bool isDifferent = false ) = 0;

        typedef std::function<Vector3d(const IModelView* pLayoutView, int index, double dLenght, double dWidth)> CallbackPointInLayout;
        /// \brief 
        /// \param[in]    ElementId modelViewId  对应modelview的elementid
        /// \param[in]    const std::wstring& viewportName 视口名称
        /// \param[in]    const Coordinate3d& coordUiView  视口对应modelivew的显示坐标系
        /// \param[in]    const Vector3d& ptLenghtStart    视口长中心线起点
        /// \param[in]    const Vector3d& ptLenghtEnd      视口长中心线终点
        /// \param[in]    double dWidht                    视口高度
        /// \param[in]    int index                        视口在图纸中的序号
        /// \param[in]    CallbackPointInLayout            求在图纸的左下点位置的回调函数
        /// \return       IDrawingViewport*
        virtual IDrawingViewport* CreateMultiViewport(ElementId modelViewId, const std::wstring& viewportName, const Coordinate3d& coordUiView, const Vector3d& ptLenghtStart,const Vector3d& ptLenghtEnd,double dWidht ,int index, CallbackPointInLayout) =0;
        
        /// \brief 
        /// \param[in]    ElementId modelViewId     对应modelview的elementid
        /// \param[in]    const std::wstring& viewportName 视口名称
        /// \param[in]    const Coordinate3d& coordUiView  视口对应modelivew的显示坐标系
        /// \param[in]    const Vector3d& point            视口在图纸的左下点
        /// \return       IDrawingViewport*
        virtual IDrawingViewport* CreateMultiViewport(ElementId modelViewId, const std::wstring& viewportName, const Coordinate3d& coordUiView, const Vector3d& point) =0;
        /// \brief 
        /// \param[in]    ElementId modelViewId     对应modelview的elementid
        /// \param[in]    const std::wstring& viewportName 视口名称
        /// \param[in]    const Vector3d& point            视口在图纸的左下点
        /// \return       IDrawingViewport*
        virtual IDrawingViewport* CreateMultiViewport(ElementId modelViewId, const std::wstring& viewportName, const Vector3d& point) = 0;

        /// \brief 基于视图坐标系创建一个多边形视口
        /// 
        /// 注意：目前仅支持全为直线段组成的多边形
        /// \param modelViewId 视口对应的ModelView的Id
        /// \param name 视口名称，视口名称唯一        
        /// \param pPolygon 代表视口范围的局部做坐标系下的多边形，局部坐标系参考pCoordinate的描述
        /// \param anchorPt 视口多边形包围盒左下点在图纸视图坐标系中的坐标
        /// \param pCoordinate 局部坐标系（传空则使用modelViewId对应的视图坐标系）
        /// \return 创建成功返回视口指针,失败返回nullptr
        virtual IDrawingViewport* CreatePolygonViewport(ElementId modelViewId, const std::wstring& viewportName, OwnerPtr<IPolygon> pPolygon, const Vector3d& anchorPt, const Coordinate3d* pCoordinate = nullptr) = 0;

        /// \brief 删除一个视口
        /// 
        /// \param pViewport 要删除的视口指针
        /// \return 返回true表示删除成功，否则删除失败
        virtual bool DeleteViewport(IDrawingViewport* pViewport) = 0;

        /// \brief 通过名字删除一个视口
        /// 
        /// \param name 要删除的视口名称
        /// \return 返回true表示删除成功，否则删除失败
        virtual bool DeleteViewport(const std::wstring& name) = 0;

        /// \brief 通过名字获取一个视口
        /// 
        /// \param name 视口名称
        /// \return 返回对应的视口指针
        virtual IDrawingViewport* GetViewport(const std::wstring& name) const = 0;

        /// \brief 获取该图纸中所有的视口
        /// 
        /// \return 返回所有视口
        virtual std::vector<IDrawingViewport*> GetAllViewports() const = 0;

        /// \brief 获取图纸上激活的视口
        ///
        /// \return 成功返回视口指针，否则返回nullptr
        virtual IDrawingViewport* GetActiveViewport() const = 0;

        /// \brief 获取视口事件
        ///
        /// \return 如成功则返回视口事件接口，失败则返回nullptr。
        static IDrawingViewportEvent* GetViewportEvent();

        /// \brief 设置是否需要启用视口的类LOD功能，绘制视口内容
        ///
        /// 视口的类LOD功能表示当视口尺寸很小，用户基本无法看清楚视口内容的场景，此时可以不重新绘制视口内容，提升视口的缩放性能，默认值为false
        /// \param isEnableViewportLODEffect 是否需要启用视口的类LOD功能，设置为true时，视口尺寸很小时会出现视口内容模糊的现象
        /// \return 返回true表示设置成功，false表示设置失败。
        virtual bool SetIsEnableViewportLODEffect(bool isNeedToDrawViewport) = 0;

        /// \brief 获取是否开启视口的类LOD功能
        /// 
        /// \return 返回true表示启用视口LOD功能，视口内容不需要实时绘制，false表示禁用视口LOD功能，需要实时绘制视口内容。
        virtual bool IsEnableViewportLODEffect() const = 0;
    };

}
